home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ADA Programming Guide
/
ADA Programming Guide.iso
/
ada_pcdp
/
ada
/
ra.ada
< prev
next >
Wrap
Text File
|
1996-01-30
|
4KB
|
145 lines
with Semaphore_Package; use Semaphore_Package;
with Text_IO; use Text_IO;
procedure RA is
type Node_Count is range 0..4;
subtype Node_ID is Node_Count range 1..Node_Count'Last;
task type Nodes is
entry Init(ID: Node_ID);
entry Request_Message(Num: Integer; ID: Node_ID);
entry Reply_Message;
end Nodes;
Node: array(Node_ID) of Nodes;
task body Nodes is
Number: Integer := 0;
High_Number: Integer := 0;
Requesting: Boolean := False;
Reply_Count: Node_Count := 0;
S: Binary_Semaphore := Init(1);
Wake_Up: Binary_Semaphore := Init(0);
Deferred: array(Node_ID) of Boolean := (others => False);
I: Node_ID;
Received_Number: Integer;
Received_ID: Node_ID;
pragma Volatile(Number);
pragma Volatile(High_Number);
pragma Volatile(Requesting);
pragma Volatile(Reply_Count);
pragma Volatile(Deferred);
task Main_Process is
entry Init;
end Main_Process;
task body Main_Process is
procedure Choose_Number is
begin
Wait(S);
Requesting := True;
Number := High_Number + 1;
Signal(S);
end Choose_Number;
procedure Send_Request is
begin
Reply_Count := 0;
for J in Node_ID loop
if J /= I then
Node(J).Request_Message(Number, I);
Put_Line(" " & Node_ID'Image(I) & " sending request to " &
Node_ID'Image(J) & " with number " &
Integer'Image(Number));
end if;
end loop;
end Send_Request;
procedure Reply_to_Deferred_Nodes is
begin
Wait(S);
Requesting := False;
Signal(S);
for J in Node_ID loop
if Deferred(J) then
Put_Line(" " & Node_ID'Image(I) & " sending deferred reply to " &
Node_ID'Image(J));
Deferred(J) := False;
Node(J).Reply_Message;
end if;
end loop;
end Reply_to_Deferred_Nodes;
begin
accept Init;
for M in 1..3 loop
Put_Line(" " & Node_ID'Image(I) & " non-critical section" );
Choose_Number;
Send_Request;
Wait(Wake_Up);
Put_Line(" " & Node_ID'Image(I) & " critical section");
Reply_to_Deferred_Nodes;
Put_Line(" " & Node_ID'Image(I) & " replied to deferred nodes");
end loop;
end Main_Process;
procedure Received_Request is
Decide_to_Defer: Boolean;
begin
Put_Line(" " & Node_ID'Image(I) & " with number " &
Integer'Image(Number) & " received request from " &
Node_ID'Image(Received_ID) & " with number " &
Integer'Image(Received_Number));
if Received_Number > High_Number then
High_Number := Received_Number;
end if;
Wait(S);
Decide_to_Defer := Requesting and
( Number < Received_Number or
(Number = Received_Number and
I < Received_ID) );
if Decide_to_Defer then
Deferred(Received_ID) := True;
Put_Line(" " & Node_ID'Image(I) & " decides to defer " &
Node_ID'Image(Received_ID));
Signal(S);
else
Put_Line(" " & Node_ID'Image(I) & " sending reply to " &
Node_ID'Image(Received_ID));
Signal(S);
Node(Received_ID).Reply_Message;
end if;
end Received_Request;
begin
accept Init(ID: Node_ID) do
I := ID;
Main_Process.Init;
end Init;
loop
select
accept Request_Message(Num: Integer; ID: Node_ID) do
Received_Number := Num;
Received_ID := ID;
end Request_Message;
Received_Request;
or
accept Reply_Message;
Reply_Count := Reply_Count + 1;
if Reply_Count = Node_ID'Last - 1 then Signal(Wake_Up); end if;
or
terminate;
end select;
end loop;
end Nodes;
begin
for J in Node_ID loop
Node(J).Init(J);
end loop;
end RA;